package com.yeskery.nut.util;

import com.yeskery.nut.core.NutException;
import java.util.*;

/**
 * Json空值的清除器，该类只能用于简单的json对象，复杂的对象请勿使用
 * @author sprout
 * 2025-04-18 09:21
 * @version 1.0
 */
public class JsonNullRemover {

    /**
     * 去除JSON字符串中的null字段
     * @param jsonString JSON字符串
     * @return 去除null字段后的JSON字符串
     */
    public static String removeNullFields(String jsonString) {
        try {
            Object json = parseJson(jsonString);
            Object cleanedJson = cleanNullFields(json);
            return toJsonString(cleanedJson);
        } catch (Exception e) {
            throw new NutException("Invalid JSON format", e);
        }
    }

    /**
     * 去除JSON字符串中的null和空字符串字段
     * @param jsonString JSON字符串
     * @return 去除null和空字符串字段后的JSON字符串
     */
    public static String removeNullOrEmptyFields(String jsonString) {
        try {
            Object json = parseJson(jsonString);
            Object cleanedJson = cleanNullOrEmptyFields(json);
            return toJsonString(cleanedJson);
        } catch (Exception e) {
            throw new NutException("Invalid JSON format", e);
        }
    }

    /**
     * 解析JSON字符串并返回对应的对象
     * @param jsonString JSON字符串
     * @return 解析后的对象
     */
    private static Object parseJson(String jsonString) {
        if (jsonString == null || jsonString.trim().isEmpty()) {
            throw new IllegalArgumentException("JSON string is empty");
        }
        jsonString = jsonString.trim();
        if (jsonString.startsWith("{") && jsonString.endsWith("}")) {
            return parseJsonObject(jsonString);
        } else if (jsonString.startsWith("[") && jsonString.endsWith("]")) {
            return parseJsonArray(jsonString);
        } else {
            throw new IllegalArgumentException("Invalid JSON format");
        }
    }

    /**
     * 解析JSON对象字符串并返回对应的对象
     * @param jsonString JSON对象字符串
     * @return 解析后的对象
     */
    private static Map<String, Object> parseJsonObject(String jsonString) {
        Map<String, Object> map = new LinkedHashMap<>();
        jsonString = jsonString.substring(1, jsonString.length() - 1).trim();

        while (!jsonString.isEmpty()) {
            int colonIndex = jsonString.indexOf(':');
            if (colonIndex == -1) {
                throw new IllegalArgumentException("Invalid JSON object format");
            }

            String key = jsonString.substring(0, colonIndex).trim();
            key = key.replaceAll("^\"|\"$", "");

            jsonString = jsonString.substring(colonIndex + 1).trim();
            Object value;

            if (jsonString.startsWith("\"")) {
                // 处理字符串值（包含转义字符）
                int endIndex = findStringEnd(jsonString);
                value = jsonString.substring(1, endIndex);
                jsonString = jsonString.substring(endIndex + 1).trim();
            } else if (jsonString.startsWith("{")) {
                int endIndex = findClosingBrace(jsonString, '{', '}');
                value = parseJsonObject(jsonString.substring(0, endIndex + 1));
                jsonString = jsonString.substring(endIndex + 1).trim();
            } else if (jsonString.startsWith("[")) {
                int endIndex = findClosingBrace(jsonString, '[', ']');
                value = parseJsonArray(jsonString.substring(0, endIndex + 1));
                jsonString = jsonString.substring(endIndex + 1).trim();
            } else if (jsonString.startsWith("null")) {
                value = null;
                jsonString = jsonString.substring(4).trim();
            } else if (jsonString.startsWith("true") || jsonString.startsWith("false")) {
                value = Boolean.parseBoolean(jsonString.substring(0, jsonString.indexOf(',') > 0 ? jsonString.indexOf(',') : jsonString.length()));
                jsonString = jsonString.substring(value.toString().length()).trim();
            } else {
                // 数字或其他值
                int endIndex = jsonString.indexOf(',');
                endIndex = (endIndex == -1) ? jsonString.length() : endIndex;
                String rawValue = jsonString.substring(0, endIndex).trim();
                try {
                    if (rawValue.contains(".")) {
                        value = Double.parseDouble(rawValue);
                    } else {
                        value = Long.parseLong(rawValue);
                    }
                } catch (NumberFormatException e) {
                    throw new IllegalArgumentException("Invalid number format in JSON string: " + rawValue);
                }
                jsonString = jsonString.substring(endIndex).trim();
            }

            map.put(key, value);

            if (jsonString.startsWith(",")) {
                jsonString = jsonString.substring(1).trim();
            }
        }
        return map;
    }

    /**
     * 解析JSON数组字符串并返回对应的对象
     * @param jsonString JSON数组字符串
     * @return 解析后的对象
     */
    private static List<Object> parseJsonArray(String jsonString) {
        List<Object> list = new ArrayList<>();
        jsonString = jsonString.substring(1, jsonString.length() - 1).trim();

        while (!jsonString.isEmpty()) {
            Object value;
            if (jsonString.startsWith("\"")) {
                int endIndex = findStringEnd(jsonString);
                value = jsonString.substring(1, endIndex);
                jsonString = jsonString.substring(endIndex + 1).trim();
            } else if (jsonString.startsWith("{")) {
                int endIndex = findClosingBrace(jsonString, '{', '}');
                value = parseJsonObject(jsonString.substring(0, endIndex + 1));
                jsonString = jsonString.substring(endIndex + 1).trim();
            } else if (jsonString.startsWith("[")) {
                int endIndex = findClosingBrace(jsonString, '[', ']');
                value = parseJsonArray(jsonString.substring(0, endIndex + 1));
                jsonString = jsonString.substring(endIndex + 1).trim();
            } else if (jsonString.startsWith("null")) {
                value = null;
                jsonString = jsonString.substring(4).trim();
            } else if (jsonString.startsWith("true") || jsonString.startsWith("false")) {
                value = Boolean.parseBoolean(jsonString.substring(0, jsonString.indexOf(',') > 0 ? jsonString.indexOf(',') : jsonString.length()));
                jsonString = jsonString.substring(value.toString().length()).trim();
            } else {
                int endIndex = jsonString.indexOf(',');
                endIndex = (endIndex == -1) ? jsonString.length() : endIndex;
                String rawValue = jsonString.substring(0, endIndex).trim();
                try {
                    if (rawValue.contains(".")) {
                        value = Double.parseDouble(rawValue);
                    } else {
                        value = Long.parseLong(rawValue);
                    }
                } catch (NumberFormatException e) {
                    throw new IllegalArgumentException("Invalid number format in JSON string: " + rawValue);
                }
                jsonString = jsonString.substring(endIndex).trim();
            }

            list.add(value);

            if (jsonString.startsWith(",")) {
                jsonString = jsonString.substring(1).trim();
            }
        }
        return list;
    }

    /**
     * 查找字符串的结束位置
     * @param s 字符串
     * @return 结束位置
     */
    private static int findStringEnd(String s) {
        int length = s.length();
        boolean escaped = false;
        for (int i = 1; i < length; i++) {
            char current = s.charAt(i);
            if (current == '"') {
                if (!escaped) {
                    return i;
                }
                escaped = false;
            } else if (current == '\\') {
                escaped = !escaped;
            } else {
                escaped = false;
            }
        }
        throw new IllegalArgumentException("Unterminated string in JSON");
    }

    /**
     * 查找指定符号的匹配位置
     * @param str 字符串
     * @param openSymbol 开始符号
     * @param closeSymbol 结束符号
     * @return 匹配位置
     */
    private static int findClosingBrace(String str, char openSymbol, char closeSymbol) {
        int count = 0;
        for (int i = 0; i < str.length(); i++) {
            char ch = str.charAt(i);
            if (ch == openSymbol) {
                count++;
            } else if (ch == closeSymbol) {
                count--;
                if (count == 0) {
                    return i;
                }
            }
        }
        throw new IllegalArgumentException("Unmatched braces in JSON string");
    }

    /**
     * 清理JSON中的空字段
     * @param json JSON对象
     * @return 清理后的JSON对象
     */
    @SuppressWarnings("unchecked")
    private static Object cleanNullFields(Object json) {
        if (json instanceof Map) {
            Map<String, Object> map = (Map<String, Object>) json;
            map.entrySet().removeIf(entry -> entry.getValue() == null);
            map.forEach((key, value) -> map.put(key, cleanNullFields(value)));
            return map;
        } else if (json instanceof List) {
            List<Object> list = (List<Object>) json;
            list.replaceAll(JsonNullRemover::cleanNullFields);
            return list;
        } else {
            return json;
        }
    }


    /**
     * 清理JSON中的空字段或空字符串
     * @param json JSON对象
     * @return 清理后的JSON对象
     */
    @SuppressWarnings("unchecked")
    private static Object cleanNullOrEmptyFields(Object json) {
        if (json instanceof Map) {
            Map<String, Object> map = (Map<String, Object>) json;
            map.entrySet().removeIf(entry -> entry.getValue() == null || StringUtils.isBlank(entry.getValue().toString()));
            map.forEach((key, value) -> map.put(key, cleanNullFields(value)));
            return map;
        } else if (json instanceof List) {
            List<Object> list = (List<Object>) json;
            list.replaceAll(JsonNullRemover::cleanNullFields);
            return list;
        } else {
            return json;
        }
    }

    /**
     * 将JSON对象转换为JSON字符串
     * @param json JSON对象
     * @return JSON字符串
     */
    @SuppressWarnings("unchecked")
    private static String toJsonString(Object json) {
        if (json instanceof Map) {
            Map<String, Object> map = (Map<String, Object>) json;
            StringBuilder sb = new StringBuilder("{");
            for (Map.Entry<String, Object> entry : map.entrySet()) {
                sb.append("\"").append(entry.getKey()).append("\":").append(toJsonString(entry.getValue())).append(",");
            }
            if (sb.length() > 1) {
                sb.setLength(sb.length() - 1);
            }
            sb.append("}");
            return sb.toString();
        } else if (json instanceof List) {
            List<Object> list = (List<Object>) json;
            StringBuilder sb = new StringBuilder("[");
            for (Object item : list) {
                sb.append(toJsonString(item)).append(",");
            }
            if (sb.length() > 1) {
                sb.setLength(sb.length() - 1);
            }
            sb.append("]");
            return sb.toString();
        } else if (json instanceof String) {
            return "\"" + json + "\"";
        } else {
            return json.toString();
        }
    }
}